/**
 * Feb 24, 2022
 */
package com.citahub.config;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.ArrayList;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import com.citahub.util.TomlUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.moandjiezana.toml.Toml;

public class ResourcesStubConfigParser extends AbstractConfigParser {

  private static final Logger logger = LoggerFactory.getLogger(ResourcesStubConfigParser.class);

  public ResourcesStubConfigParser(String configPath) {
    super(configPath + File.separator);
  }

  public static final String CONNECTION_DEFAULT_PATH = "/chains/cita/";

  public static final List<String> CONNECTION_DEFAULT_NAMES =
      Lists.newArrayList("connection.toml", "driver.toml");

  public ResourceStubConfig config() throws IOException {
    String configPath = getConfigPath();
    String filePath = null == configPath || configPath.contains("null") ? CONNECTION_DEFAULT_PATH : configPath;
    String connectionPath = filePath + CONNECTION_DEFAULT_NAMES.get(0);

    Toml connectionToml = new TomlUtils(connectionPath).getToml();
    Map<String, Object> connectionConfig = connectionToml.toMap();

    List<Map<String, Object>> resourcesConfigValue =
        (List<Map<String, Object>>) connectionConfig.get("resources");
    if (CollectionUtils.isEmpty(resourcesConfigValue)) {
      resourcesConfigValue = Lists.newArrayList();
    }
    List<ResourceStubConfig.Resource> resources =
        getResourceConfig(connectionPath, resourcesConfigValue);

    String driverPath = filePath + CONNECTION_DEFAULT_NAMES.get(1);

    Toml driverToml = new TomlUtils(driverPath).getToml();
    Map<String, Object> driverConfig = driverToml.toMap();
    Map<String, String> chainConfigValue = (Map<String, String>) driverConfig.get("chain");
    if (MapUtils.isEmpty(chainConfigValue)) {
      chainConfigValue = Maps.newHashMap();
    }
    String chainPath = chainConfigValue.get("chainPath");

    ResourceStubConfig resourceStubConfig = new ResourceStubConfig();
    resourceStubConfig.setChainPath(chainPath);
    resourceStubConfig.setResources(resources);
    return resourceStubConfig;
  }

  public List<ResourceStubConfig.Resource> getResourceConfig(String configFile,
      List<Map<String, Object>> resourcesConfigValue) throws IOException {
    List<ResourceStubConfig.Resource> resourceList = Lists.newArrayList();

    for (Map<String, Object> stringStringMap : resourcesConfigValue) {
      String name = (String) stringStringMap.get("name");
      requireFieldNotNull(name, "resources", "name", configFile);

      String type = (String) stringStringMap.get("type");
      requireFieldNotNull(type, "resources", "type", configFile);

      String address = (String) stringStringMap.get("contractAddress");
      requireFieldNotNull(address, "resources", "contractAddress", configFile);

      String[] methods = null;
      if (!Objects.isNull(stringStringMap.get("methods"))) {
        ArrayList methodArr = (ArrayList) stringStringMap.get("methods");
        methods = (String[]) methodArr.toArray(new String[methodArr.size()]);
      }

      ResourceStubConfig.Resource resource = new ResourceStubConfig.Resource();
      resource.setName(name);
      resource.setType(type);
      resource.setValue(address);
      resource.setMethods(methods);

      resourceList.add(resource);
    }

    logger.debug("resources: {}", resourceList);

    return resourceList;
  }

}
